﻿using Analyzor.entity;
using CodeSmith.Engine;
using SOAFramework.Library;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Analyzor
{
    public partial class frmCode : Form
    {
        public frmCode()
        {
            InitializeComponent();
        }

        private void frmCode_Load(object sender, EventArgs e)
        {
            Run();
            MessageBox.Show("over");
        }

        public void Run()
        {
            string output = AppDomain.CurrentDomain.BaseDirectory + "template\\";
            string templatePath = @"D:\git\FrankTemplate\stock\";
            string[] templateFiles = Directory.GetFiles(templatePath);
            List<Interface> table = DbContext.StockClient.Queryable<Interface>().ToList();
            Dictionary<string, DataTable> columnsDic = new Dictionary<string, DataTable>();
            TemplateEngine engine = new TemplateEngine(templatePath);
            var tableList = DbContext.StockClient.DbMaintenance.GetTableInfoList(true);
            table.RemoveAll(x =>
            {
                DataTable columns = DbContext.StockClient.Queryable<Parameter>().Where(t => t.IntefaceId.Equals(x.Id) && t.ArgTtype == 1).ToDataTable();
                columnsDic[x.Code] = columns;
                bool setted = true;
                foreach (DataRow dataRow in columns.Rows)
                {
                    if (dataRow["is_primarykey"].ToString() == "1")
                    {
                        setted = false;
                        break;
                    }
                }
                return setted;
            });
            foreach (var row in table)
            {
                string tableName = row.Code;
                string description = row.Description;
                DataTable columns = columnsDic[tableName];
                Dictionary<string, object> argMap = new Dictionary<string, object>();
                argMap["TableName"] = tableName;
                argMap["Description"] = description;
                argMap["ClassName"] = StringUtil.ToPascalCase(tableName);

                DataTable innerArgs = DbContext.StockClient.Queryable<Parameter>().Where(t => t.IntefaceId.Equals(row.Id) && t.ArgTtype == 0).ToDataTable();
                argMap["Columns"] = columns;
                argMap["InputArgs"] = innerArgs;
                List<string> fileList = new List<string>();
                fileList.Add($@"{templatePath}java\entity.cst");
                fileList.Add($@"{templatePath}java\bean.cst");
                fileList.Add($@"{templatePath}java\request.cst");
                fileList.Add($@"{templatePath}java\mapper.cst");
                fileList.Add($@"{templatePath}java\service.cst");

                GenerateFile(engine, argMap, fileList, output, tableName);
                bool enableDrop = false;
                if (enableDrop && tableList.Exists(t => t.Name.Equals(row.Code)))
                {
                    DbContext.StockClient.DbMaintenance.DropTable(tableName);
                    tableList.RemoveAll(t => t.Name.Equals(tableName));
                }
                if (!tableList.Exists(t => t.Name.Equals(row.Code)))
                {
                    string sql = GenerateString(engine, argMap, $"{templatePath}sql.cst");
                    DbContext.StockClient.Ado.ExecuteCommand(sql, new List<SugarParameter>() { });
                }
                try
                {
                    string sql = GenerateString(engine, argMap, $"{templatePath}index.cst");
                    DbContext.StockClient.Ado.ExecuteCommand(sql, new List<SugarParameter>() { });
                }
                catch (Exception ex)
                {

                }
            }
            Dictionary<string, object> map = new Dictionary<string, object>();
            map["Interfaces"] = table.ToDataTable();
            GenerateFile(engine, map, new List<string> { $"{templatePath}tushareservice.cst" }, output, "TushareProService");
        }

        public void GenerateFile(TemplateEngine engine, Dictionary<string, object> argMap, List<string> templateList, string outputPath, string className)
        {
            try
            {

                foreach (string templateFile in templateList)
                {
                    FileInfo fileInfo = new FileInfo(templateFile);
                    string file = fileInfo.Name.Split('.')[0];
                    string targetFile = $@"{outputPath}{file}\{StringUtil.ToPascalCase(className)}{StringUtil.ToPascalCase(file)}.java";
                    string code = GenerateString(engine, argMap, templateFile);
                    FileInfo target = new FileInfo(targetFile);
                    if (!target.Directory.Exists)
                    {
                        target.Directory.Create();
                    }
                    File.WriteAllText(targetFile, code);
                }
            }
            catch (Exception ex)
            {

            }
        }

        public string GenerateString(TemplateEngine engine, Dictionary<string, object> argMap, string templateFile)
        {
            CompileTemplateResult result = engine.Compile(templateFile);
            CodeTemplate template = result.CreateTemplateInstance();
            foreach (var key in argMap.Keys)
            {
                template.SetProperty(key, argMap[key]);
            }
            string code = template.RenderToString();
            return code;
        }
    }
}
